/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/

#include "base.h"
#include "vstring.h"

/*
	IMPLEMENTAÇÃO DAS FUNÇÕES DE: base.h
*/

/******************************************************************************
 *        read_string
 * parametros:
 *		string: ponteiro para caracteres que guardará a string lida.
 *
 * recebe uma string, faz a leitura necessária em um vetor de caracteres e
 * aloca a memória necessária para copiar os caracteres lidos para a string.
 *****************************************************************************/
void read_string(char** string)
{
    char c[100] = {'\0'};
    int size,i = 0;
    scanf("%c", &c[i]);

    while(c[i] != '\n')
        scanf("%c", &c[++i]);
    c[i] = '\0';
    size = strlen(c);

    *string = (char*) malloc(size * sizeof(char));
    strcpy(*string,c);
}

/*	Função que aloca memória e em caso de erro
	finaliza a execução do programa	*/
void* safe_alloc(unsigned int size)
{
    void* ptr = malloc(size);
    if(ptr == NULL)
    {
        fprintf(stderr, "fatal error: fail to allocate memory!\n");
        exit(EXIT_FAILURE);
    }
    return ptr;
}

/*  Função para desalocar memória de forma segura */
void safe_free(void *pt)
{
    if(pt != NULL)
    {
        free(pt);
        pt = NULL;
    }
}

/*	Seta o seed do rand	*/
void set_rand_seed(int seed)
{
    if(seed != 0)
    {
        // inicializa a seed do random
        // caso a mesma seja passada
        srand(seed);
    }
}
/*	Função que retorna um número randômico
	Parâmetro:
		- int range: número aleatório de 1 a range	*/
int get_rand_number(int range, int seed)
{
    set_rand_seed(seed);
    // retorna um número aleatório de 1 a range
    return rand() % range + 1;
}

/*	Chama a função get_rand_number passando time(NULL) como semente	*/
int get_random_number(int range)
{
    // chama o get_rand_number sem
    // alterar o seed
    return get_rand_number(range, (int)time(0));
}

/*
	Função que faz o programa esperar.
	Parâmetro:
		- int seconds: segundos a esperar
*/
void wait_(int seconds)
{
	clock_t endwait;
	endwait = clock() + seconds * CLOCKS_PER_SEC;
	while(clock() < endwait) { }
}

/*Captura a extensão do arquivo para preencher o content type do header http*/

char* get_extension(char *nome)
{
    char *ext = strrchr(nome, '.');
    if (!ext) return NULL;
    if (strcmp(ext, ".html") == 0 || strcmp(ext, ".htm") == 0) return "text/html";
    if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) return "image/jpeg";
    if (strcmp(ext, ".gif") == 0) return "image/gif";
    if (strcmp(ext, ".png") == 0) return "image/png";
    if (strcmp(ext, ".ico") == 0) return "image/ico";
    if (strcmp(ext, ".txt") == 0) return "text/txt";
    if (strcmp(ext, ".css") == 0) return "text/css";
    if (strcmp(ext, ".au") == 0) return "audio/basic";
    if (strcmp(ext, ".wav") == 0) return "audio/wav";
    if (strcmp(ext, ".avi") == 0) return "video/x-msvideo";
    if (strcmp(ext, ".mpeg") == 0 || strcmp(ext, ".mpg") == 0) return "video/mpeg";
    if (strcmp(ext, ".mp3") == 0) return "audio/mpeg";
    return "*/*";
}

int hexa_to_dec(vstring *str,int *var)
{
    int i = 0,sinal = 0;
    *var = 0;

    for(i = 0; i < str->length && sinal != -1; i++)
        if((str->pt[i] >= 'A' || str->pt[i] >= 'a') && (str->pt[i] <= 'F' || str->pt[i] <= 'f'))
        {
            if(str->pt[i] >= 'A' && str->pt[i] <= 'F')
                str->pt[i] += 32;
        }
        else
            if(str->pt[i] == '-')
                sinal = 1;
            else
                if(str->pt[i] < '0' || str->pt[i] > '9')
                    sinal = -1;

    if(sinal != -1)
    {
        for(i = 0; i < str->length; i++)
        {
            if(str->pt[i] != '-')
            {
                if(str->pt[i] >= 'a' && str->pt[i] <= 'f')
                    *var = *var * 16 + (str->pt[i] - 87);
                else
                    *var = *var * 16 + (str->pt[i] - 48);
            }
        }
        if(sinal)
            *var = *var * -1;
        return 1;
    }
    return 0;
}

int string_to_integer(vstring *str,int *var)
{
    int i = 0,sinal = 0,base = 10;
    *var = 0;

    for(i = 0; i < str->length && sinal != -1; i++)
        if(str->pt[i] == '-')
            sinal = 1;
        else
            if(str->pt[i] < '0' || str->pt[i] > '9')
                sinal = -1;

    if(sinal != -1)
    {
        for(i = 0; i < str->length; i++)
            if(str->pt[i] != '-')
                *var = *var * base + (str->pt[i] - 48);
        if(sinal)
            *var = *var * -1;

        return 1;
    }
    return 0;
}

void integer_to_string(vstring **c,int num)
{
    int i,aux;
    aux = num;

    for(i = 0; aux > 0; i++)
        aux = aux / 10;

    alloc_string(c,i);
    (*c)->length = i;

    for(i--; i >= 0; i--)
    {
        (*c)->pt[i] = 48 + (num % 10);
        num = num / 10;
    }
    (*c)->pt[(*c)->length] = '\0';
}

int convert_month(vstring *mon)
{
    if(strcmp(mon->pt,"Jan") == 0)
        return 0;
    if(strcmp(mon->pt,"Feb") == 0)
        return 1;
    if(strcmp(mon->pt,"Mar") == 0)
        return 2;
    if(strcmp(mon->pt,"Apr") == 0)
        return 3;
    if(strcmp(mon->pt,"May") == 0)
        return 4;
    if(strcmp(mon->pt,"Jun") == 0)
        return 5;
    if(strcmp(mon->pt,"Jul") == 0)
        return 6;
    if(strcmp(mon->pt,"Aug") == 0)
        return 7;
    if(strcmp(mon->pt,"Sep") == 0)
        return 8;
    if(strcmp(mon->pt,"Oct") == 0)
        return 9;
    if(strcmp(mon->pt,"Nov") == 0)
        return 10;
    if(strcmp(mon->pt,"Dec") == 0)
        return 11;
    return -1;
}